package grpcserver

import (
	"context"

	ticketv1 "github.com/devops-smartbot/devops-smartbot/proto/gen/go/ticket/v1"
	"github.com/devops-smartbot/devops-smartbot/services/ticket-service/internal/service"
)

// Server implements the TicketServiceServer API.
type Server struct {
	ticketv1.UnimplementedTicketServiceServer
	service service.Service
}

// New constructs a new gRPC server.
func New(service service.Service) *Server {
	return &Server{service: service}
}

// ListTickets delegates to service layer and maps response types.
func (s *Server) ListTickets(ctx context.Context, req *ticketv1.ListTicketsRequest) (*ticketv1.ListTicketsResponse, error) {
	tickets, total, err := s.service.ListTickets(ctx, req)
	if err != nil {
		return nil, err
	}

	resp := &ticketv1.ListTicketsResponse{Total: int32(total)}
	for _, t := range tickets {
		resp.Tickets = append(resp.Tickets, &ticketv1.Ticket{
			Id:             t.ID,
			Number:         t.TicketNumber,
			Title:          t.Title,
			Description:    t.Description,
			Status:         t.Status,
			Priority:       t.Priority,
			AssigneeId:     t.AssignedTo,
			CreatedAtUnix:  t.CreatedAt.Unix(),
			UpdatedAtUnix:  t.UpdatedAt.Unix(),
			RelatedAlertId: t.AlertID,
			Type:           t.Type,
		})
	}

	return resp, nil
}

// GetTicket returns a single ticket.
func (s *Server) GetTicket(ctx context.Context, req *ticketv1.GetTicketRequest) (*ticketv1.Ticket, error) {
	ticket, err := s.service.GetTicket(ctx, req.GetId())
	if err != nil {
		return nil, err
	}
	if ticket == nil {
		return nil, nil
	}

	return &ticketv1.Ticket{
		Id:             ticket.ID,
		Number:         ticket.TicketNumber,
		Title:          ticket.Title,
		Description:    ticket.Description,
		Status:         ticket.Status,
		Priority:       ticket.Priority,
		AssigneeId:     ticket.AssignedTo,
		CreatedAtUnix:  ticket.CreatedAt.Unix(),
		UpdatedAtUnix:  ticket.UpdatedAt.Unix(),
		RelatedAlertId: ticket.AlertID,
		Type:           ticket.Type,
	}, nil
}

// CreateTicket creates a new ticket.
func (s *Server) CreateTicket(ctx context.Context, req *ticketv1.CreateTicketRequest) (*ticketv1.CreateTicketResponse, error) {
	ticket, err := s.service.CreateTicket(ctx, req)
	if err != nil {
		return nil, err
	}

	return &ticketv1.CreateTicketResponse{
		Ticket: &ticketv1.Ticket{
			Id:             ticket.ID,
			Number:         ticket.TicketNumber,
			Title:          ticket.Title,
			Description:    ticket.Description,
			Status:         ticket.Status,
			Priority:       ticket.Priority,
			AssigneeId:     ticket.AssignedTo,
			CreatedAtUnix:  ticket.CreatedAt.Unix(),
			UpdatedAtUnix:  ticket.UpdatedAt.Unix(),
			RelatedAlertId: ticket.AlertID,
			Type:           ticket.Type,
		},
	}, nil
}

// GetTicketStatistics returns ticket statistics.
func (s *Server) GetTicketStatistics(ctx context.Context, req *ticketv1.GetTicketStatisticsRequest) (*ticketv1.GetTicketStatisticsResponse, error) {
	return s.service.GetTicketStatistics(ctx)
}

// UpdateTicket updates an existing ticket.
func (s *Server) UpdateTicket(ctx context.Context, req *ticketv1.UpdateTicketRequest) (*ticketv1.UpdateTicketResponse, error) {
	ticket, err := s.service.UpdateTicket(ctx, req)
	if err != nil {
		return nil, err
	}

	return &ticketv1.UpdateTicketResponse{
		Ticket: &ticketv1.Ticket{
			Id:             ticket.ID,
			Number:         ticket.TicketNumber,
			Title:          ticket.Title,
			Description:    ticket.Description,
			Status:         ticket.Status,
			Priority:       ticket.Priority,
			AssigneeId:     ticket.AssignedTo,
			CreatedAtUnix:  ticket.CreatedAt.Unix(),
			UpdatedAtUnix:  ticket.UpdatedAt.Unix(),
			RelatedAlertId: ticket.AlertID,
			Type:           ticket.Type,
		},
	}, nil
}

// AddComment adds a comment to a ticket.
func (s *Server) AddComment(ctx context.Context, req *ticketv1.AddCommentRequest) (*ticketv1.AddCommentResponse, error) {
	ticket, err := s.service.AddComment(ctx, req.TicketId, req.Content, req.UserName, req.IsInternal)
	if err != nil {
		return nil, err
	}

	return &ticketv1.AddCommentResponse{
		Ticket: &ticketv1.Ticket{
			Id:             ticket.ID,
			Number:         ticket.TicketNumber,
			Title:          ticket.Title,
			Description:    ticket.Description,
			Status:         ticket.Status,
			Priority:       ticket.Priority,
			AssigneeId:     ticket.AssignedTo,
			CreatedAtUnix:  ticket.CreatedAt.Unix(),
			UpdatedAtUnix:  ticket.UpdatedAt.Unix(),
			RelatedAlertId: ticket.AlertID,
			Type:           ticket.Type,
		},
	}, nil
}

var _ ticketv1.TicketServiceServer = (*Server)(nil)
